package com.h2.ref.server.user.openid;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.h2.ref.server.user.IUserListener;
import com.h2.ref.server.user.IUserService;
import com.h2.ref.server.user.UserService.UserExt;
import com.h2.ref.server.user.model.User;

public class UserServiceOpenId implements UserDetailsService {
   
   private IOpenIdDao _openIdDao;
   
   private IUserService _userService;
   
   ////
   ////
   
   public void init() {
      getUserService().getUserListeners().add(new IUserListener() {
         
         @Override
         public void onDeleteUser(User user) {
            deleteUser(user);
         }
         
         @Override
         public void onAddUser(User user) {}
      });
   }
   
   /* (non-Javadoc)
    * @see org.springframework.security.core.userdetails
    *       .UserDetailsService#loadUserByUsername(java.lang.String)
    */
   @Override
   public UserDetails loadUserByUsername(String identityUrl)
         throws UsernameNotFoundException, DataAccessException {
      return findByUid(identityUrl);
   }
   
   protected UserDetails findByUid(String identityUrl)
         throws UsernameNotFoundException {

      OpenId openIdDetail = getOpenIdDao().findByIdentityUrl(identityUrl);
      if (openIdDetail == null || openIdDetail.getUserId() == null) {
         throw new UsernameNotFoundException("No user associated.");
      }
      User user = getUserService().findByUserId(
            openIdDetail.getUserId());
      if (user == null) {
         throw new UsernameNotFoundException("No user found.");
      }
      return UserExt.createUserExt(user);
   }
   
   public Collection<OpenId> findOpenIds(User user) {
      return getOpenIdDao().findOpenIds(user);
   }
   
   public void addOpenId(OpenId openId) {
      getOpenIdDao().addOpenId(openId);
   }
   
   public void deleteOpenId(OpenId openId) {
      getOpenIdDao().deleteOpenId(openId);
   }
   
   public void deleteUser(User user) {
      getOpenIdDao().deleteUser(user);
   }

   /**
    * @return the openIdDao
    */
   public IOpenIdDao getOpenIdDao() {
      return _openIdDao;
   }

   /**
    * @param openIdDao the openIdDao to set
    */
   @Required
   public void setOpenIdDao(IOpenIdDao openIdDao) {
      _openIdDao = openIdDao;
   }

   /**
    * @return the userService
    */
   public IUserService getUserService() {
      return _userService;
   }

   /**
    * @param userService the userService to set
    */
   @Required
   public void setUserService(IUserService userService) {
      _userService = userService;
   }
}
